home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / misc / emu / arosdev.lha / AROS / workbench / c / dir.c < prev    next >
C/C++ Source or Header  |  1997-01-27  |  5KB  |  267 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: dir.c,v 1.12 1997/01/27 00:22:36 ldp Exp $
  4.  
  5.     Desc: Dir CLI command
  6.     Lang: english
  7. */
  8. #include <exec/memory.h>
  9. #include <proto/exec.h>
  10. #include <dos/dos.h>
  11. #include <dos/exall.h>
  12. #include <dos/datetime.h>
  13. #include <proto/dos.h>
  14. #include <proto/utility.h>
  15. #include <utility/tagitem.h>
  16. #include <utility/utility.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <memory.h>
  20. #include <aros/debug.h>
  21.  
  22. static const char version[] = "$VER: Dir 1.9 (4.10.1996)\n";
  23.  
  24. struct UtilityBase *UtilityBase;
  25.  
  26. struct table
  27. {
  28.     char ** entries;
  29.     int     num, max;
  30. };
  31.  
  32. char ** files;
  33. int num_files, max_files;
  34. char ** dirs;
  35. int num_dirs, max_dirs;
  36.  
  37. static int AddEntry (struct table * table, char * entry)
  38. {
  39.     char * dup;
  40.  
  41.     if (table->num == table->max)
  42.     {
  43.     int new_max = table->max + 128;
  44.     char ** new_entries;
  45.  
  46.     new_entries = AllocVec (sizeof(char *)*new_max, MEMF_ANY);
  47.  
  48.     if (!new_entries)
  49.         return 0;
  50.  
  51.     if (table->num)
  52.     {
  53.         CopyMemQuick (table->entries, new_entries, sizeof(char *)* table->num);
  54.         FreeVec (table->entries);
  55.     }
  56.  
  57.     table->entries = new_entries;
  58.     table->max = new_max;
  59.     }
  60.  
  61.     if (!(dup = strdup (entry)) )
  62.     return 0;
  63.  
  64.     table->entries[table->num ++] = dup;
  65.     return 1;
  66. }
  67.  
  68. static int compare_strings (const void * s1, const void * s2)
  69. {
  70.     return strcasecmp (*(char **)s1, *(char **)s2);
  71. }
  72.  
  73. int indent = 0;
  74. static void showline (char * fmt, LONG args[])
  75. {
  76.     int t;
  77.  
  78.     for (t=0; t<indent; t++)
  79.     VPrintf ("    ", NULL);
  80.  
  81.     VPrintf (fmt, args);
  82. }
  83.  
  84. struct
  85. {
  86.     char * dir;
  87.     char * opt;
  88.     ULONG all;
  89. } args = {
  90.     NULL,
  91.     NULL,
  92.     0
  93. };
  94. char path[1024];
  95.  
  96. static LONG do_dir (void)
  97. {
  98.     BPTR dir;
  99.     LONG loop;
  100.     struct ExAllControl *eac;
  101.     struct ExAllData *ead;
  102.     static UBYTE buffer[4096];
  103.     LONG error=0;
  104.     struct table dirs, files;
  105.  
  106.     dirs.entries = files.entries = NULL;
  107.     dirs.max = files.max = 0;
  108.     dirs.num = files.num = 0;
  109.  
  110.     dir=Lock(path,SHARED_LOCK);
  111.     if(dir)
  112.     {
  113.     eac=AllocDosObject(DOS_EXALLCONTROL,NULL);
  114.     if(eac!=NULL)
  115.     {
  116.         int t;
  117.         IPTR argv[3];
  118.  
  119.         eac->eac_LastKey=0;
  120.         do
  121.         {
  122.         loop=ExAll(dir,(struct ExAllData *)buffer,4096,ED_COMMENT,eac);
  123.         if(!loop&&IoErr()!=ERROR_NO_MORE_ENTRIES)
  124.         {
  125.             error=RETURN_ERROR;
  126.             break;
  127.         }
  128.         if(eac->eac_Entries)
  129.         {
  130.             ead=(struct ExAllData *)buffer;
  131.             do
  132.             {
  133.             if (!AddEntry (ead->ed_Type > 0 ? &dirs : &files, ead->ed_Name))
  134.             {
  135.                 loop = 0;
  136.                 error=RETURN_ERROR;
  137.                 VPrintf ("out of memory\n", NULL);
  138.                 break;
  139.             }
  140.  
  141.             ead=ead->ed_Next;
  142.             }while(ead!=NULL);
  143.         }
  144.         }while(loop);
  145.         FreeDosObject(DOS_EXALLCONTROL,eac);
  146.  
  147.         if (!error)
  148.         {
  149.         if (dirs.num)
  150.         {
  151.             char * ptr;
  152.             int added_slash = 0;
  153.  
  154.             indent ++;
  155.  
  156.             qsort (dirs.entries, dirs.num, sizeof (char *),
  157.             compare_strings);
  158.  
  159.             ptr = path + strlen (path);
  160.  
  161.             if (*path && ptr[-1] != ':' && ptr[-1] != '/')
  162.             {
  163.             *ptr ++ = '/';
  164.             *ptr = 0;
  165.  
  166.             added_slash = 1;
  167.             }
  168.  
  169.             for (t=0; t<dirs.num; t++)
  170.             {
  171.             argv[0] = (IPTR) dirs.entries[t];
  172.  
  173.             if (args.all)
  174.             {
  175.                 strcpy (ptr, dirs.entries[t]);
  176.  
  177.                 showline ("%-25.s <DIR>\n", argv);
  178.                 do_dir ();
  179.             }
  180.             else
  181.                 showline ("    %-25.s <DIR>\n", argv);
  182.             }
  183.  
  184.             if (added_slash)
  185.             ptr[-1] = 0;
  186.  
  187.             indent --;
  188.         }
  189.  
  190.         if (files.num)
  191.         {
  192.             qsort (files.entries, files.num, sizeof (char *),
  193.             compare_strings);
  194.  
  195.             for (t=0; t<files.num; t+=2)
  196.             {
  197.             argv[0] = (IPTR) (files.entries[t]);
  198.             argv[1] = (IPTR) (t+1 < files.num ? files.entries[t+1] : "");
  199.             if (args.all)
  200.                 showline ("    %-25.s %-25.s\n", argv);
  201.             else
  202.                 showline ("%-25.s %-25.s\n", argv);
  203.             }
  204.         }
  205.         }
  206.  
  207.         if (dirs.num)
  208.         {
  209.         for (t=0; t<dirs.num; t++)
  210.         {
  211.             free (dirs.entries[t]);
  212.         }
  213.  
  214.         if (dirs.entries)
  215.             FreeVec (dirs.entries);
  216.         }
  217.  
  218.         if (files.num)
  219.         {
  220.         for (t=0; t<files.num; t++)
  221.         {
  222.             free (files.entries[t]);
  223.         }
  224.  
  225.         if (files.entries)
  226.             FreeVec (files.entries);
  227.         }
  228.     }else
  229.     {
  230.         SetIoErr(ERROR_NO_FREE_STORE);
  231.         error=RETURN_ERROR;
  232.     }
  233.     UnLock(dir);
  234.     }
  235.  
  236.     return error;
  237. }
  238.  
  239. int main (int argc, char ** argv)
  240. {
  241.     struct RDArgs *rda;
  242.     LONG error=0;
  243.  
  244.     UtilityBase=(struct UtilityBase *)OpenLibrary(UTILITYNAME,39);
  245.  
  246.     if (!UtilityBase)
  247.     return RETURN_ERROR;
  248.  
  249.     rda=ReadArgs("Dir,OPT/K,ALL/S",(IPTR *)&args,NULL);
  250.     if(rda!=NULL)
  251.     {
  252.     strcpy (path, args.dir!=NULL?args.dir:"");
  253.  
  254.     error = do_dir ();
  255.  
  256.     FreeArgs(rda);
  257.     }else
  258.     error=RETURN_FAIL;
  259.     if(error)
  260.     PrintFault(IoErr(),"Dir");
  261.  
  262.     CloseLibrary((struct Library *)UtilityBase);
  263.  
  264.     return error;
  265. }
  266.  
  267.